package org.hdlh.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.hdlh.constants.ReqType;
import org.hdlh.constants.RpcConstants;
import org.hdlh.core.Header;
import org.hdlh.core.RpcProtocol;
import org.hdlh.core.RpcRequest;
import org.hdlh.core.RpcResponse;
import org.hdlh.serial.ISerializer;
import org.hdlh.serial.SerializerManager;

import java.util.List;

/**
 * 解码器
 */
@Slf4j
public class RpcDecoder extends ByteToMessageDecoder {


    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        log.info("begin rpc decoder");

        if(in.readableBytes() < RpcConstants.HEAD_TOTAL_LENG){
            return;
        }

        //标记读取区域开始索引
        in.markReaderIndex();

        //读取2个字节
        short maci = in.readShort();
        if(maci != RpcConstants.MAGIC){
            throw new IllegalArgumentException("Illegal request parameter 'magic'," + maci);
        }

        //读取一个字节的序列化类型
        byte serialType = in.readByte();
        //读取一个字节的消息类型
        byte reqType = in.readByte();
        //读取请求id
        long requestId = in.readLong();
        //请求数据报文长度
        int dataLength = in.readInt();

        if(in.readableBytes() < dataLength){
            log.info("报文长度不够");
            //还原
            in.resetReaderIndex();
            return;
        }

        byte[] content = new byte[dataLength];
        in.readBytes(content);

        Header header = new Header(maci, serialType, reqType, requestId, dataLength);
        ISerializer iSerializer = SerializerManager.getSerializer(serialType);

        ReqType reqType1 = ReqType.findByCode(reqType);
        switch (reqType1){
            case REQUEST:
                //内容处理
                RpcRequest request = iSerializer.deserialize(content, RpcRequest.class);
                RpcProtocol<RpcRequest> rpcRequestRpcProtocol = new RpcProtocol<RpcRequest>();
                rpcRequestRpcProtocol.setHeader(header);
                rpcRequestRpcProtocol.setContent(request);
                out.add(rpcRequestRpcProtocol);
                break;
            case RESPONSE:
                RpcResponse rpcResponse = iSerializer.deserialize(content, RpcResponse.class);
                RpcProtocol<RpcResponse> rpcResponseRpcProtocol = new RpcProtocol<RpcResponse>();
                rpcResponseRpcProtocol.setHeader(header);
                rpcResponseRpcProtocol.setContent(rpcResponse);
                out.add(rpcResponseRpcProtocol);
                break;
            case HEARTBEAT:
                break;
            default:
                break;
        }




        log.info("end rpc decoder");
    }
}
